﻿using UnityEngine;
using System.Collections.Generic;

#if UNITY_EDITOR
using UnityEditor;
#endif

namespace CWM.Skinn.FFD
{
	[ExecuteInEditMode]
	public class LatticeDeformer : MonoBehaviour
    {
		[Header("Resolution")]
		[Range (1, 13)]
		public int m_x = 1;
		[Range (1, 13)]
		public int m_y = 1;
		[Range (1, 13)]
		public int m_z = 1;

        [Header("Advanced")]
        public bool m_editBounds = false;
        public Bounds m_bounds = new Bounds();

		[HideInInspector]
		public Vector3 dividedBoundsSize;
		[HideInInspector]
		public float markerSize;
		[HideInInspector]
		public SkinnedMeshRenderer skinnedMeshRender = null;
		[HideInInspector]
		public Mesh orignalMesh = null;

        private void Start() { }

        private void OnEnable() { SkinnGizmos.OnSceneGUI -= OnSceneGUI; SkinnGizmos.OnSceneGUI += OnSceneGUI; }

        private void OnDestroy() { SkinnGizmos.OnSceneGUI -= OnSceneGUI; }

        public void OnSceneGUI()
        {
#if UNITY_EDITOR
            UpdateMarkers();

            if (!enabled || !gameObject.activeInHierarchy) return;

            if (!m_editBounds)
            {
                if (Selection.activeTransform == transform && Tools.current == Tool.None) Tools.current = Tool.Move;
                return;
            }
            else if (Selection.activeTransform == transform && Tools.current != Tool.None) Tools.current = Tool.None;

            var center = transform.TransformPoint(m_bounds.center);
            var handlesColor = Handles.color;
            Handles.color = Color.green;
            Handles.DrawWireCube(center, m_bounds.size);

            var bound = m_bounds;
            var size = bound.size;
            var points = bound.ToPointArray();
            var handleSize = HandleUtility.GetHandleSize(center) * 0.25f;

            for (int i = 0; i < points.Length; i++) size = Handles.DoScaleHandle(size, transform.TransformPoint(points[i]), Quaternion.identity, handleSize);
            center = Handles.DoPositionHandle(center, Quaternion.identity);

            bound.size = size;
            bound.center = transform.InverseTransformPoint(center);
            m_bounds = bound;

            Handles.color = handlesColor;
#endif
        }


        public static void UpdateMarkers()
        {
#if UNITY_EDITOR
            var selection = Selection.objects;
            if (selection.Length < 2) return;
            LatticeDeformer lattice = null;
            for (int i = 0; i < selection.Length; i++)
            {
                var go = selection[i] as GameObject; if (!go) continue;
                var mark = go.GetComponent<LatticeMarker>(); if (!mark || !mark.lattice) continue;
                lattice = mark.lattice;
                break;
            }
            if (!lattice) return;
            var newSelection = new List<Object>(selection.Length);
            for (int i = 0; i < selection.Length; i++)
            {
                var go = selection[i] as GameObject; if (!go) continue;
                var mark = go.GetComponent<LatticeMarker>(); if (!mark || mark.lattice != lattice || mark.weightCount < 1) continue;
                newSelection.Add(mark.gameObject); 
            }
            if (selection.Length != newSelection.Count) Selection.objects = newSelection.ToArray();
#endif
        }


        public static LatticeDeformer CreateFFD(Renderer renderer)
        {
            if (SkinnEx.IsNullOrNotVailid(renderer)) return null;
            var ffd = LatticeUtility.CreateLatticeDeformer(renderer.GetSharedMesh(), renderer.transform, null);
            return ffd;
        }

        public static LatticeDeformer CreateFFD(LatticeDeformer rig)
        {
            if (!rig || !rig.skinnedMeshRender || !rig.orignalMesh) return null;
            rig.skinnedMeshRender.sharedMesh = rig.orignalMesh;
            var ffd = LatticeUtility.CreateLatticeDeformer(rig.skinnedMeshRender.sharedMesh, rig.skinnedMeshRender.transform, rig);
            return ffd;
        }
        
    }
}